﻿using System.Windows;
using System.Threading;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Controls;
using LisBioGUIWPF.Controls;
using LisBioGUIWPF.Controls.Alumno;
using LisBioGUIWPF.Controls.Encargado;
using System.ComponentModel;
using DAO;
using System.Collections.Generic;
using Entidades;
using System;
using Negocio;
using LisBioGUIWPF.GuiFunctions;

namespace LisBioGUIWPF
{
    /// <summary>
    /// Interaction logic for LisBio.xaml
    /// </summary>
    public partial class LisBio : Window
    {

        private string pathImages;
        private List<EntidadBase> proyectosActuales;
        private bool godMode;
        private EntidadInvestigador encargadoLis;
        private ImageControl image;

        private System.Windows.Forms.NotifyIcon m_notifyIcon;
        private WindowState m_storedWindowState = WindowState.Normal;

        public LisBio()
        {
            InitializeComponent();
            image = new ImageControl(this);
            this.colocarImagenPrincipal();
            this.godMode = false;
            this.godModeOpciones();
            this.menuAdministrar.IsEnabled = false;
            this.btnSalidas.IsEnabled = false;
            this.cerrarSesion_Click(null, null);
            this.iniciarSesion_Click(null, null);

            m_notifyIcon = new System.Windows.Forms.NotifyIcon();
            m_notifyIcon.BalloonTipText = "LisBio se encuentra minimizado. Presione el icono en el System Tray para mostrar";
            m_notifyIcon.BalloonTipTitle = "LisBio";
            m_notifyIcon.Text = "LisBio";
            m_notifyIcon.Icon = new System.Drawing.Icon(@"img\UbuntuSZ.ico");
            m_notifyIcon.Click += new EventHandler(m_notifyIcon_Click);

            //Obtener path de la carpeta donde se guardan las imagenes
            try
            {
                Entidades.Configuracion.XmlOperations xml = new Entidades.Configuracion.XmlOperations();
                Entidades.Configuracion.ConfiguracionXML config = xml.deserialize("config.xml");
                this.PathImages = config.ImagesDirectory;

                this.cargarMenuProyectos();
                this.cargarMiembrosPresentes();
            }
            catch (System.IO.FileNotFoundException ex)
            {
                MessageBox.Show("Debe configurar la Base de Datos\ny la carpeta de imagenes",
                    "Error de Configuracion");
                Configuracion config = new Configuracion(this);
                config.Show();
            }
            catch (Exception ex)
            {
                MessageBox.Show("No se pudo establecer la conexion con la Base de Datos.");
            }
        }

        void m_notifyIcon_Click(object sender, EventArgs e)
        {
            Show();
            WindowState = m_storedWindowState;
        }

        void OnStateChanged(object sender, EventArgs args)
        {
            if (WindowState == WindowState.Minimized)
            {
                Hide();
                if (m_notifyIcon != null)
                    m_notifyIcon.ShowBalloonTip(2000);
            }
            else
                m_storedWindowState = WindowState;
        }
        void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            CheckTrayIcon();
        }

        void CheckTrayIcon()
        {
            ShowTrayIcon(!IsVisible);
        }

        void ShowTrayIcon(bool show)
        {
            if (m_notifyIcon != null)
                m_notifyIcon.Visible = show;
        }

        private void cargarMiembrosPresentes()
        {
            AsistenciaDAO daoAsistencia = new AsistenciaDAO();
            List<EntidadAsistencia> listAsistencias = new List<EntidadAsistencia>();
            listAsistencias = daoAsistencia.leerSalidasNull();

            for (int i = 0; i < listAsistencias.Count; i++ )
            {
                int id = listAsistencias[i].Investigador.Id;
                InvestigadorDAO daoInvestigador = new InvestigadorDAO();
                EntidadInvestigador investigador = new EntidadInvestigador();
                investigador.Id = id;

                investigador = (EntidadInvestigador)daoInvestigador.leer(investigador);
                this.agregarInvestigadorMenu(investigador);
            }
        }

        void menuConfiguracion_Click(object sender, RoutedEventArgs e)
        {
            Configuracion config = new Configuracion(this);
            config.Show();
        }

        private void colocarImagenPrincipal()
        {
            image.setDefaultImage();
            this.borderHuella.Child = image;
        }

        private void btnInvestigador_Click(object sender, RoutedEventArgs e)
        {
            InvestigadorControl investigador = new InvestigadorControl(this, false);
            this.borderControles.Child = investigador;
            this.colocarImagenPrincipal();
        }

        private void btnProyecto_Click(object sender, RoutedEventArgs e)
        {
            ProyectoControl proyecto = new ProyectoControl(this);
            this.borderControles.Child = proyecto;
            this.colocarImagenPrincipal();
        }

        private void iniciarSesion_Click(object sender, RoutedEventArgs e)
        {
            SesionControl sesion = new SesionControl(this);
            this.borderControles.IsEnabled = true;
            this.borderControles.Child = sesion;
            this.borderControles.Visibility = Visibility.Visible;
            this.colocarImagenPrincipal();
        }

        private void asistencia_click(object sender, RoutedEventArgs e)
        {
            InvestigadorControl investigador = new InvestigadorControl(this, true);
            this.borderControles.Child = investigador;
            this.colocarImagenPrincipal();
        }

        private void cerrarSesion_Click(object sender, RoutedEventArgs e)
        {
            if(this.encargadoLis != null) SesionControl.logoutEncargado(this.encargadoLis, this);
            this.borderControles.Child = null;
            this.colocarImagenPrincipal();
            this.expander.IsEnabled = false;
            this.menuAdministrar.IsEnabled = false;
            this.borderControles.Visibility = Visibility.Hidden;
            this.lblEncargado.Content = "Encargado: ";
            this.menuAsistencia.IsEnabled = false;
            this.btnSalidas.IsEnabled = false;
            this.menuIniciar.IsEnabled = true;
            this.menuCerrar.IsEnabled = false;
            this.borderHuella.IsEnabled = false;
        }

        private void configuracion(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.F1)
            {
                this.menuConfiguracion_Click(sender, null);
            }
            else if (e.Key == System.Windows.Input.Key.F5)
            {
                this.asistencia_click(null, null);
            }
        }

        private void menuEncargado_Click(object sender, RoutedEventArgs e)
        {
            this.colocarImagenPrincipal();
            this.borderControles.Child = null;

            EncargadoData.Operacion oper;
            if (sender == this.menuNuevo)
            {
                EncargadoControl encargadoControl = new EncargadoControl();
                oper = EncargadoData.Operacion.NUEVO;
                EncargadoData encargadoData = new EncargadoData(this, oper, encargadoControl);
                encargadoData.txtNombre.Focus();
                this.borderHuella.Child = encargadoData;
            }
            else if (sender == this.menuModificar)
            {
                oper = EncargadoData.Operacion.MODIFICAR;
                EncargadoControl encargadoControl = new EncargadoControl(this, oper);
                this.borderControles.Child = encargadoControl;
            }
            else
            {
                oper = EncargadoData.Operacion.ELIMINAR;
                EncargadoControl encargadoControl = new EncargadoControl(this, oper);
                this.borderControles.Child = encargadoControl;
            }

        }

        private void expander_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            this.expander.IsExpanded = true;
        }
        private void btnEncuestas_Click(object sender, RoutedEventArgs e)
        {
            AlumnoData alumnoData = new AlumnoData(this, AlumnoData.Operacion.NUEVO, null);
            alumnoData.txtNombre.Focus();
            this.borderHuella.Child = alumnoData;
            //Cuando existan mas encuestas se usara el codigo a continuacino
            /*EncuestaControl encuestas = new EncuestaControl(this, AlumnoData.Operacion.NUEVO);
            this.borderControles.Child = encuestas;
            this.colocarImagenPrincipal();*/

        }

        /*
         * Antes de cerrar la aplicacion se verifica si hay miembros que no registraron su salida 
         * del Laboratorio y se le informa al encargado.
         */
        private void LisBio_Closing(object sender, CancelEventArgs e)
        {
            AsistenciaDAO daoAsistencia = new AsistenciaDAO();
            List<EntidadAsistencia> listAsistencias = new List<EntidadAsistencia>();
            listAsistencias = daoAsistencia.leerSalidasNull();

            if (listAsistencias.Count > 0)
            {
                MessageBoxResult result = MessageBox.Show("Hay miembros que no registraron su salida en el Laboratorio.\n"+
                "Para forzar la registracion seleccione 'Salidas Generales' en el menu.\n¿Desea salir de la aplicacion?", "Asistencia",
                MessageBoxButton.YesNo);

                if (result == MessageBoxResult.No)
                {
                    e.Cancel = true;
                    return;
                }
            }

            m_notifyIcon.Dispose();
            m_notifyIcon = null;
            this.cerrarSesion_Click(null, null);
        }

        private void btnSalidas_Click(object sender, RoutedEventArgs e)
        {
            AsistenciaDAO daoAsistencia = new AsistenciaDAO();
            List<EntidadAsistencia> listAsistencias = new List<EntidadAsistencia>();
            listAsistencias = daoAsistencia.leerSalidasNull();

            if (listAsistencias.Count > 0)
            {
                for (int i = 0; i < listAsistencias.Count; i++)
                {
                    ReglaBase regla;

                    DateTime fechaEntrada;
                    fechaEntrada = (DateTime)listAsistencias[i].FechaYHoraEntrada;
                    if (fechaEntrada.Year == DateTime.Now.Year && fechaEntrada.Month == DateTime.Now.Month && fechaEntrada.Day == DateTime.Now.Day)
                    {
                        DateTime date = DateTime.Now;
                        listAsistencias[i].FechaYHoraSalida = date;
                        regla = new ReglaBase(listAsistencias[i], daoAsistencia, ReglaBase.Operacion.UPDATE);
                    }
                    else
                    {
                        //Se registran las salidas que se olvidaron y que tienen fecha anterior al dia actual
                        int año;
                        int mes;
                        int dia;
                        int hora;

                        año = fechaEntrada.Year;
                        mes = fechaEntrada.Month;
                        dia = fechaEntrada.Day;

                        if (fechaEntrada.Hour > 20)
                        {
                            hora = 23;
                            DateTime fechaSalida = new DateTime(año, mes, dia, hora, 0, 0);
                            listAsistencias[i].FechaYHoraSalida = fechaSalida;
                        }
                        else
                        {
                            hora = fechaEntrada.Hour + 3;
                            DateTime fechaSalida = new DateTime(año, mes, dia, hora, 0, 0);
                            listAsistencias[i].FechaYHoraSalida = fechaSalida;
                        }

                        regla = new ReglaBase(listAsistencias[i], daoAsistencia, ReglaBase.Operacion.UPDATE);
                    }

                    try
                    {
                        regla.execute();
                    }
                    catch (Excepciones.InvalidEntityException exc)
                    {
                        MessageBox.Show("No se pudo registrar la Salida", "Asistencia");
                    }
                    catch (Exception exception)
                    {
                        MessageBox.Show("Se ha producido el siguiente error:\n" + exception.Message, "Error!");

                        MessageBoxResult result = MessageBox.Show("Desea reportar el error?", "Error Desconocido", MessageBoxButton.YesNo);

                        if (result == MessageBoxResult.Yes)
                        {
                            ReportBugs reportar = new ReportBugs();
                            reportar.Show();
                        }
                    }
                }
                this.image.quitarTodosMiembros();
                this.colocarImagenPrincipal();
                this.notification("Salidas Registradas!");
            }
        }

        public string PathImages
        {
            get { return this.pathImages; }
            set { this.pathImages = value; }
        }

        public void cargarMenuProyectos()
        {
            this.proyectosActuales = CargarComponente.listarProyecto();

            //Cargar proyectos actuales en el Menu
            foreach (EntidadBase proyecto in this.proyectosActuales)
            {
                MenuItem item = new MenuItem();
                item.Height = 25;
                item.Click += new RoutedEventHandler(itemProyectos_Click);
                item.Header = ((EntidadProyecto)proyecto).Nombre;
                this.menuProyectos.Items.Add(item);
            }
        }

        void itemProyectos_Click(object sender, RoutedEventArgs e)
        {
            LisBioGUIWPF.Controls.Project.ProjectData projectData = new LisBioGUIWPF.Controls.Project.ProjectData(this,
                LisBioGUIWPF.Controls.Project.ProjectData.Operacion.DETALLES, null);

            //Cargando la entidad seleccionada al userData para que cargue los datos en pantalla
            int pos = 0;
            foreach (EntidadProyecto entidad in this.proyectosActuales)
            {
                if (((MenuItem)e.Source).Header.ToString() == entidad.Nombre) break;
                pos++;
            }

            projectData.Project = (EntidadProyecto) this.proyectosActuales[pos];
            projectData.cargarDatos();

            this.borderHuella.Child = projectData;
        }

        public void agregarInvestigadorMenu(EntidadInvestigador investigador)
        {
            this.image.agregarMiembro(investigador);
        }

        public void quitarInvestigadorMenu(EntidadInvestigador investigador)
        {
            this.image.quitarMiembro(investigador);
            this.colocarImagenPrincipal();
        }

        private void godModeOpciones()
        {
            this.menuNuevo.IsEnabled = this.godMode;
            this.menuEliminar.IsEnabled = this.godMode;
            this.menuAdministrar.IsEnabled = this.godMode;
            this.btnSalidas.IsEnabled = this.godMode;

            this.expander.IsEnabled = this.godMode;
            this.borderControles.IsEnabled = this.godMode;
            this.borderControles.Child = null;
            this.lblEncargado.Content = "GOD MODE";

            if (!this.godMode)
            {
                this.cerrarSesion_Click(null, null);
            }
        }

        public bool GodMode
        {
            get { return godMode; }
            set { this.godMode = value; this.godModeOpciones(); }
        }

        public EntidadInvestigador EncargadoLis
        {
            get { return this.encargadoLis; }
            set { this.encargadoLis = value; }
        }

        private void btnAlumno_Click(object sender, RoutedEventArgs e)
        {
            AlumnoControl alumno = new AlumnoControl(this);
            this.borderControles.Child = alumno;
            this.colocarImagenPrincipal();
        }

        private void btnReportes_Click(object sender, RoutedEventArgs e)
        {
            ReportesControl reporte = new ReportesControl(this);
            this.borderControles.Child = reporte;
            this.colocarImagenPrincipal();
        }

        public void notification(string mensaje)
        {
            this.lblNotificacion.Content = mensaje;
            DoubleAnimation oLabel = new DoubleAnimation();
            oLabel.From = 0;
            oLabel.To = 1;
            oLabel.AutoReverse = true;
            oLabel.Duration = new Duration(new TimeSpan(0, 0, 0, 3, 0));
            this.lblNotificacion.BeginAnimation(Label.OpacityProperty, oLabel);
            
        }

    }
}
